package org.jeecg.modules.platformMasterEndPoint.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.jx.constant.FileConstants;
import org.jeecg.modules.miniAppCustomerEndPoint.entity.JxSiteMenuDo;
import org.jeecg.modules.miniAppCustomerEndPoint.mapper.JxSiteMenuMapper;
import org.jeecg.modules.platformMasterEndPoint.entity.JxFoodRepositoryDo;
import org.jeecg.modules.platformMasterEndPoint.entity.JxFoodRepositoryVo;
import org.jeecg.modules.platformMasterEndPoint.mapper.JxFoodRepositoryMapper;
import org.jeecg.modules.platformMasterEndPoint.mapper.JxStoreRepositoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Api(tags = "店铺菜品管理")
@RestController
@RequestMapping("/jx/jxFoodManage")
@Slf4j
public class JxFoodManageController {

    @Autowired
    private JxFoodRepositoryMapper jxFoodRepositoryMapper;

    @Autowired
    private JxSiteMenuMapper jxSiteMenuMapper;

    @Autowired
    private JxStoreRepositoryMapper jxStoreRepositoryMapper;

    /**
     * 接口调用场景
     * 1. 菜品页面，点击【新增菜品】按钮，跳转到 新增菜品页面，填写完菜品信息后，点击 【保存】按钮，调用此接口，此种场景下，请求参数中 foodId为null
     * 2. 菜品页面，表格中操作列，点击【编辑】按钮，跳转到 新增菜品页面，填写完菜品信息后，点击 【保存】按钮，调用此接口，此种场景下，请求参数中 foodId不为null
     *
     * @param foodRepositoryVo
     * @return
     */
    @ApiOperation("平台管理员或站长 向店铺信息库中录入一个新的店铺")
    @PostMapping("/addOrEditFoodInfo")
    public Result<?> addOrEditFoodInfo(@RequestBody() JxFoodRepositoryVo foodRepositoryVo) throws Exception {

        if (foodRepositoryVo.getFoodId() != null && !foodRepositoryVo.getFoodId().isEmpty()) {
            // 更新菜品信息
            JxFoodRepositoryDo jxFoodRepositoryDo = buildFoodRepositoryInfo(foodRepositoryVo);
            jxFoodRepositoryDo.setId(foodRepositoryVo.getFoodId());
            int updateCount = jxFoodRepositoryMapper.updateById(jxFoodRepositoryDo);
            if (updateCount == 1) {
                log.info("菜品信息更新成功，店铺id: {}, 菜品id: {}", jxFoodRepositoryDo.getStoreId(), jxFoodRepositoryDo.getId());
                return Result.ok("菜品信息更新成功");
            } else {
                return Result.error("菜品信息更新失败，联系后台技术人员进行定位");
            }
        } else {
            // 新增菜品，录入新菜品到菜品库中
            // 根据店铺名称和菜品名称进行查询，同一个店铺，不允许录入重复的菜品信息
            List<JxFoodRepositoryDo> list1 = jxFoodRepositoryMapper.selectList(new LambdaQueryWrapper<JxFoodRepositoryDo>()
                    .eq(JxFoodRepositoryDo::getStoreName, foodRepositoryVo.getStoreName())
                    .eq(JxFoodRepositoryDo::getFoodName, foodRepositoryVo.getFoodName()));

            if (list1 != null & list1.size() > 0) {
                return Result.error(450, "店铺: " + foodRepositoryVo.getStoreName() + ", 菜品名称: " + foodRepositoryVo.getFoodName() + "已存在菜品信息库中，不能录入重复的菜品");
            }

            JxFoodRepositoryDo jxFoodRepositoryDo = buildFoodRepositoryInfo(foodRepositoryVo);
            int count = jxFoodRepositoryMapper.insert(jxFoodRepositoryDo);

            HashMap<String, Object> resultData = new HashMap<>();
            if (count == 1) {
                resultData.put("foodId", jxFoodRepositoryDo.getId());
                log.info("新增菜品成功，店铺id: {}, 菜品id: {}", jxFoodRepositoryDo.getStoreId(), jxFoodRepositoryDo.getId());
                return Result.ok(resultData);
            } else {
                return Result.error("录入新菜品失败，联系后台技术人员进行定位");
            }
        }
    }

    /**
     * 查看某个店铺下的所有的菜品，包括上架和未上架的菜品
     * 接口使用场景
     * 1. 店铺&菜品管理页面，表格中 菜品个数列，可以点击菜品格式超链接，跳转到菜品页面，以表格的形式展示该站点下的所有菜品
     *
     * @return
     */
    @ApiOperation("查看某个店铺下的所有的菜品")
    @GetMapping("/queryFoodsByStoreId")
    public Result<?> queryAllFoodsByStoreId(
            @RequestParam("storeId") String storeId,
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize) {

        Page<JxFoodRepositoryDo> page = new Page<>(pageNo, pageSize);
        Page<JxFoodRepositoryDo> pageFoods = jxFoodRepositoryMapper.selectPage(page, new LambdaQueryWrapper<JxFoodRepositoryDo>().eq(JxFoodRepositoryDo::getStoreId, storeId));
        List<JSONObject> formatedFoods = new ArrayList<>();
        for (int i = 0; i < pageFoods.getRecords().size(); i++) {
            JxFoodRepositoryDo foodRepositoryDo = pageFoods.getRecords().get(i);
            JSONObject foodInfo = new JSONObject();

            foodInfo.put("foodId", foodRepositoryDo.getId());
            foodInfo.put("foodName", foodRepositoryDo.getFoodName());
            foodInfo.put("storeId", foodRepositoryDo.getStoreId());
            foodInfo.put("storeName", foodRepositoryDo.getStoreName());
            foodInfo.put("foodImage", foodRepositoryDo.getImage());
            foodInfo.put("description", foodRepositoryDo.getDescription());
            foodInfo.put("foodTypeName", foodRepositoryDo.getFoodTypeName());
            foodInfo.put("specification", JSONArray.parse(foodRepositoryDo.getSpecification()));
            foodInfo.put("limitCount", foodRepositoryDo.getLimitCount());
            foodInfo.put("storePrice", foodRepositoryDo.getStorePrice());
            foodInfo.put("required", foodRepositoryDo.isRequired());
            foodInfo.put("sort", foodRepositoryDo.getSort());
            // 向站长或平台管理员展示某个店铺中的菜品信息时，需要展示菜品的 上架或下架状态，站长和平台管理员也可以根据 店铺菜品供应情况以及用户对菜品的反馈，调整菜品的 上架或下架 状态
            foodInfo.put("foodState", foodRepositoryDo.getState());
            formatedFoods.add(foodInfo);
        }

        JSONObject resultData = new JSONObject();
        resultData.put("foods", formatedFoods);
        resultData.put("totalPages", pageFoods.getPages());
        resultData.put("totalCount", pageFoods.getTotal());
        resultData.put("currentPage", pageFoods.getCurrent());
        return Result.ok(resultData);
    }

    /**
     * 根据店铺名或菜品名进行模糊搜索，查找符合搜索条件的菜品列表，不是查询某个店铺内的菜品，而是从所以店铺的菜品中进行搜索
     * 接口调用场景
     * 1. 菜品管理页面，通过搜索框输入关键字（匹配 菜品名或店铺名），点击 【查询】按钮，调用此接口
     *
     * @return
     */
    @GetMapping("/queryFoodsByKeyword")
    public Result<?> queryFoodsByKeyword(
            @RequestParam("keyword") String keyword,
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize) {

        Page<JxFoodRepositoryDo> page = new Page<>(pageNo, pageSize);
        Page<JxFoodRepositoryDo> pageList = jxFoodRepositoryMapper.selectPage(page,
                new LambdaQueryWrapper<JxFoodRepositoryDo>()
                        .eq(JxFoodRepositoryDo::getDelFlag, 0)
                        .and(wrap -> wrap.like(JxFoodRepositoryDo::getFoodName, keyword).or().like(JxFoodRepositoryDo::getStoreName, keyword))
                        .orderByAsc(JxFoodRepositoryDo::getFoodName));

        JSONObject resultData = new JSONObject();
        List<JSONObject> foods = new ArrayList<>();
        for (int k = 0; k < pageList.getRecords().size(); k++) {
            JxFoodRepositoryDo foodRepositoryDo = pageList.getRecords().get(k);
            JSONObject formatedFoodInfo = new JSONObject();
            formatedFoodInfo.put("foodId", foodRepositoryDo.getId());
            formatedFoodInfo.put("foodName", foodRepositoryDo.getFoodName());
            formatedFoodInfo.put("foodImage", foodRepositoryDo.getImage());
            formatedFoodInfo.put("description", foodRepositoryDo.getDescription());
            formatedFoodInfo.put("specification", JSONArray.parse(foodRepositoryDo.getSpecification()));
            formatedFoodInfo.put("storeId", foodRepositoryDo.getStoreId());
            formatedFoodInfo.put("storeName", foodRepositoryDo.getStoreName());
            formatedFoodInfo.put("storePrice", foodRepositoryDo.getStorePrice());
            formatedFoodInfo.put("foodTypeName", foodRepositoryDo.getFoodTypeName());
            formatedFoodInfo.put("limitCount", foodRepositoryDo.getLimitCount());
            formatedFoodInfo.put("state", foodRepositoryDo.getState());
            formatedFoodInfo.put("required", foodRepositoryDo.isRequired());
            formatedFoodInfo.put("sort", foodRepositoryDo.getSort());

            foods.add(formatedFoodInfo);
        }

        resultData.put("foods", foods);
        resultData.put("totalCount", pageList.getTotal());
        resultData.put("pageNo", pageNo);
        resultData.put("pageSize", pageSize);
        resultData.put("pages", pageList.getPages());
        return Result.ok(resultData);
    }

    /**
     * 接口调用场景
     * 1. 菜品页面，以表格的形式展示各个菜品简要信息，点击菜品名（带下划线，超链接效果），调用此接口，加载菜品的详细信息
     *
     * @return
     */
    @GetMapping("/queryFoodById")
    public Result<?> queryFoodById(
            @RequestParam("foodId") String foodId) {

        List<JxFoodRepositoryDo> list = jxFoodRepositoryMapper.selectList(
                new LambdaQueryWrapper<JxFoodRepositoryDo>()
                        .eq(JxFoodRepositoryDo::getId, foodId)
                        .eq(JxFoodRepositoryDo::getDelFlag, 0));

        JSONObject formatedFoodInfo = new JSONObject();
        if (list != null && list.size() > 0) {
            JxFoodRepositoryDo foodRepositoryDo = list.get(0);
            formatedFoodInfo.put("storeId", foodRepositoryDo.getStoreId());
            formatedFoodInfo.put("storeName", foodRepositoryDo.getStoreName());
            formatedFoodInfo.put("foodId", foodRepositoryDo.getId());
            formatedFoodInfo.put("foodName", foodRepositoryDo.getFoodName());
            formatedFoodInfo.put("description", foodRepositoryDo.getDescription());
            formatedFoodInfo.put("storePrice", foodRepositoryDo.getStorePrice());
            formatedFoodInfo.put("image", foodRepositoryDo.getImage());
            formatedFoodInfo.put("limitCount", foodRepositoryDo.getLimitCount());
            formatedFoodInfo.put("foodTypeName", foodRepositoryDo.getFoodTypeName());
            formatedFoodInfo.put("specification", JSONArray.parseArray(foodRepositoryDo.getSpecification()));
            formatedFoodInfo.put("state", foodRepositoryDo.getState());
            formatedFoodInfo.put("required", foodRepositoryDo.isRequired());
            formatedFoodInfo.put("sort", foodRepositoryDo.getSort());
        }

        return Result.ok(formatedFoodInfo);
    }

    /**
     * 接口调用场景
     * 1. 菜品页面，表格中会展示各个菜品的状态，点击操作列中的 【上架/下架】 按钮后，切换菜品上架或下架状态
     *
     * @return
     */
    @PutMapping("/changeFoodSupplyState")
    public Result<?> changeFoodSupplyState(
            @RequestParam("storeId") String storeId,
            @RequestParam("foodId") String foodId, @RequestParam("newState") String newState) {

        try {
            updateFoodSupplyState(storeId, foodId, newState);
            return Result.ok("将菜品状态更新为【" + newState + "】成功");
        } catch (Exception ex) {
            log.error("将菜品供应状态切换为【{}】失败，相关表更新操作已回滚，请联系后台技术人员进行数据一致性确认和问题排查", newState);
            log.error("{}", ex);
            return Result.error("将菜品状态更新为【" + newState + "】失败，请联系后台技术人员进行处理");
        }
    }

    /**
     * 将菜品库 jx_food_repository 和 jx_site_menu 表中 状态都进行修改
     *
     * @param storeId
     * @param foodId
     * @param newState
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateFoodSupplyState(String storeId, String foodId, String newState) throws Exception {

        JxFoodRepositoryDo foodRepositoryDo = new JxFoodRepositoryDo();
        try {
            // yes 上架中，no 已下架
            foodRepositoryDo.setState(newState);
            jxFoodRepositoryMapper.update(foodRepositoryDo, new UpdateWrapper<JxFoodRepositoryDo>().eq("store_id", storeId).eq("id", foodId));
            // 将 jx_site_menu 中的菜品状态进行更新
            JxSiteMenuDo jxSiteMenuDo = new JxSiteMenuDo();
            jxSiteMenuDo.setState(newState);
            jxSiteMenuMapper.update(jxSiteMenuDo, new UpdateWrapper<JxSiteMenuDo>().eq("store_id", storeId).eq("food_id", foodId));
        } catch (Exception ex) {
            log.error("{}", ex);
            throw new Exception("触发事务rollback");
        }
    }

    /**
     * 接口调用场景
     * 1. 菜品页面，表格中会展示各个菜品的状态，点击操作列中的 【编辑】 按钮后，跳转到菜品编辑页面，修改完信息后，点击【保存】按钮调用此接口
     *
     * @return
     */
    @PutMapping("/editFood")
    public Result<?> editFood(
            @RequestParam("foodId") String foodId,
            @RequestBody() JxFoodRepositoryVo foodRepositoryVo) throws Exception {

        JxFoodRepositoryDo jxFoodRepositoryDo = buildFoodRepositoryInfo(foodRepositoryVo);
        jxFoodRepositoryDo.setId(foodId);
        int updateCount = jxFoodRepositoryMapper.updateById(jxFoodRepositoryDo);
        if (updateCount == 1) {
            log.info("菜品信息更新成功，店铺id: {}, 菜品id: {}", jxFoodRepositoryDo.getStoreId(), jxFoodRepositoryDo.getId());
            return Result.ok("菜品信息更新成功");
        } else {
            return Result.error("菜品信息更新失败，联系后台技术人员进行定位");
        }
    }

    /**
     * 创建 JxFoodRepositoryDo 对象，并填充各个字段的值
     * 使用场景
     * 1. 新增或更新菜品信息时，前端调用接口时，会传递菜品信息，包括需要修改的和没有修改的，为了简化接口传参定义，更新时，属性值无论是否有更新，都一起传递给后端，后端直接更新整条记录，不用再去区分更新那些字段，不更新那些字段
     *
     * @param foodRepositoryVo
     * @return
     */
    private JxFoodRepositoryDo buildFoodRepositoryInfo(JxFoodRepositoryVo foodRepositoryVo) throws Exception {
        JxFoodRepositoryDo jxFoodRepositoryDo = new JxFoodRepositoryDo();
        jxFoodRepositoryDo.setFoodName(foodRepositoryVo.getFoodName());
        String storeId = foodRepositoryVo.getStoreId();
        File storeImageUploadDir = new File(Paths.get(FileConstants.IMAGE_FOOD_UPLOAD_DIR , storeId , "foods").toUri());
        if (!storeImageUploadDir.exists()) {
            storeImageUploadDir.mkdirs();
        }
        if (foodRepositoryVo.getImage().trim().startsWith("http")) {
            log.info("调用参数中的图片链接为: {}, 是url，属于编辑菜品信息场景，且没有更新图片，不需要重新移动图片，不需要重新生成图片url", foodRepositoryVo.getImage());
            jxFoodRepositoryDo.setImage(foodRepositoryVo.getImage());
        } else {
            log.info("调用参数中的图片链接为: {},不是url ，需要移动图片，并生成图片url", foodRepositoryVo.getImage());
            try {
                Path tempPath =  Paths.get(FileConstants.FILE_UPLOAD_TEMP_DIR , foodRepositoryVo.getImage());
                Path imagePath = Paths.get(storeImageUploadDir.getAbsolutePath(), foodRepositoryVo.getImage());
                Files.move(tempPath, imagePath);
                log.info("temp: {}, imagePath: {}", tempPath, imagePath);
                jxFoodRepositoryDo.setImage(FileConstants.IMAGE_URL_BASE + storeId + "/foods/" + foodRepositoryVo.getImage());
            } catch (IOException e) {
                log.error("录入新菜品时，将临时目录下的图片移动到 正式目录失败");
                log.error("{}", e);
                throw new Exception("录入新菜品时，将临时目录下的图片移动到 正式目录失败");
            }
        }
        jxFoodRepositoryDo.setDescription(foodRepositoryVo.getDescription());
        jxFoodRepositoryDo.setSpecification(foodRepositoryVo.getSpecification().toJSONString());
        jxFoodRepositoryDo.setStoreId(foodRepositoryVo.getStoreId());
        jxFoodRepositoryDo.setStoreName(foodRepositoryVo.getStoreName());
        jxFoodRepositoryDo.setStorePrice(foodRepositoryVo.getStorePrice());
        jxFoodRepositoryDo.setFoodTypeName(foodRepositoryVo.getFoodTypeName());
        jxFoodRepositoryDo.setState(foodRepositoryVo.getState());
        jxFoodRepositoryDo.setRequired(foodRepositoryVo.isRequired());
        jxFoodRepositoryDo.setSort(foodRepositoryVo.getSort());
        jxFoodRepositoryDo.setCreateTime(new Date());

        return jxFoodRepositoryDo;
    }

//    public String moveFileAndReturnUrl() throws Exception {
//        String storeId = foodRepositoryVo.getStoreId();
//        File storeImageUploadDir = new File(Paths.get(FileConstants.IMAGE_FOOD_UPLOAD_DIR , storeId , "foods").toUri());
//        if (!storeImageUploadDir.exists()) {
//            storeImageUploadDir.mkdirs();
//        }
//        String url = FileConstants.IMAGE_URL_BASE + storeId + "/foods/" + foodRepositoryVo.getImage();
//        try {
//            Path tempPath =  Paths.get(FileConstants.FILE_UPLOAD_TEMP_DIR , foodRepositoryVo.getImage());
//            Path imagePath = Paths.get(storeImageUploadDir.getAbsolutePath(), foodRepositoryVo.getImage());
//            Files.move(tempPath, imagePath);
//            log.info("temp: {}, imagePath: {}", tempPath, imagePath);
//            jxFoodRepositoryDo.setImage(FileConstants.IMAGE_URL_BASE + storeId + "/foods/" + foodRepositoryVo.getImage());
//        } catch (IOException e) {
//            log.error("录入新菜品时，将临时目录下的图片移动到 正式目录失败");
//            log.error("{}", e);
//            throw new Exception("录入新菜品时，将临时目录下的图片移动到 正式目录失败");
//        }
//
//        return url;
//    }

    /**
     * 接口使用场景
     * 1. 菜品页面，表格中，点击操作列中的 删除，标记删除某个菜品
     *
     * @return
     */
    @DeleteMapping("/deleteFood")
    public Result<?> deleteFoodById(@RequestParam("foodId") String foodId) {

        int deleteCount = jxFoodRepositoryMapper.deleteById(foodId);
        if (deleteCount == 1) {
            log.info("成功删除菜品");
            return Result.ok("删除菜品成功");
        } else {
            return Result.ok("删除菜品失败，请联系后台技术人员进行处理");
        }
    }

    // todo 需要同步标记 删除 jx_site_menu 表中的记录
    public void deleteFoodBothRepositoryAndMenu() {

    }

    /**
     * 查询为站点配置的菜品的 店铺合作价，佣金模式和数值； 此接口和 店铺管理中的 queryStoreCommissionByStoreId 很像
     *
     * @return
     */
    @GetMapping("/queryFoodCommission")
    public Result<?> queryFoodCommission(
            @RequestParam("siteId") String siteId,
            @RequestParam("foodId") String foodId) {

        List<JxSiteMenuDo> list = jxSiteMenuMapper.selectList(
                new LambdaQueryWrapper<JxSiteMenuDo>().eq(JxSiteMenuDo::getSiteId, siteId).eq(JxSiteMenuDo::getFoodId, foodId)
                        .eq(JxSiteMenuDo::getDelFlag, 0));

        JSONObject resultData = new JSONObject();
        if (list != null && list.size() > 0) {
            JxSiteMenuDo siteMenuDo = list.get(0);
            resultData.put("storePrice", siteMenuDo.getStorePrice());
            resultData.put("platFormCommissionType", siteMenuDo.getPlatFormCommissionType());
            resultData.put("platFormCommissionValue", siteMenuDo.getPlatFormCommissionValue());
            resultData.put("siteMasterCommissionType", siteMenuDo.getSiteMasterCommissionType());
            resultData.put("siteMasterCommissionValue", siteMenuDo.getSiteMasterCommissionValue());

            return Result.ok(resultData);
        } else {
            return Result.error("无法查找到该菜品的信息，请联系后台技术人员进行处理");
        }
    }

    /**
     * 保存修改后的店铺佣金模式和金额
     * 接口调用场景
     * 1. 管理员或站长 修改为某个站点配置的店铺的菜品 拥挤模式和金额后，使用改接口保存修改后的佣金模式和金额
     *
     * @return
     */
    @PutMapping("/editFoodCommission")
    public Result<?> editStoreCommission(
            @RequestBody() JSONObject requestBody) {

        String siteId = requestBody.getString("siteId");
        String foodId = requestBody.getString("foodId");
        Integer storePrice = requestBody.getInteger("storePrice");
        Short platFormCommissionType = requestBody.getShort("platFormCommissionType");
        Integer platFormCommissionValue = requestBody.getInteger("platFormCommissionValue");
        Short siteMasterCommissionType = requestBody.getShort("siteMasterCommissionType");
        Integer siteMasterCommissionValue = requestBody.getInteger("siteMasterCommissionValue");

        JxSiteMenuDo jxSiteMenuDo = new JxSiteMenuDo();
        jxSiteMenuDo.setStorePrice(storePrice);
        jxSiteMenuDo.setPlatFormCommissionType(platFormCommissionType);
        jxSiteMenuDo.setPlatFormCommissionValue(platFormCommissionValue);
        jxSiteMenuDo.setSiteMasterCommissionType(siteMasterCommissionType);
        jxSiteMenuDo.setSiteMasterCommissionValue(siteMasterCommissionValue);

        int updateCount = jxSiteMenuMapper.update(jxSiteMenuDo, new LambdaQueryWrapper<JxSiteMenuDo>().eq(JxSiteMenuDo::getSiteId, siteId).eq(JxSiteMenuDo::getFoodId, foodId));
        if (updateCount == 1) {
            log.info("站点id: {}，菜品id：{} 合作价和佣金更新成功", siteId, foodId);
            return Result.ok("菜品店铺合作价和佣金更新成功");
        } else {
            log.error("站点id: {}，菜品id：{} 合作价和佣金更新失败", siteId, foodId);
            return Result.ok("菜品店铺合作价和佣金更新失败，请联系后台技术人员进行处理");
        }
    }
}
